﻿@page "/administration"
@using BlazorBlogs.Data;
@using BlazorBlogs.Data.Models;
@using Microsoft.AspNetCore.Identity;
@inject UserManager<ApplicationUser> _UserManager
@inject RoleManager<IdentityRole> _RoleManager
@inject AuthenticationStateProvider AuthenticationStateProvider
@inject IConfiguration _configuration
@inject DisqusState DisqusState
@inherits OwningComponentBase<BlogsService>

<AuthorizeView>
    <Authorized>
        @if (@context.User.IsInRole(ADMINISTRATION_ROLE))
        {
            @if (ColUsers == null)
            {
                <p><em>Loading...</em></p>
            }
            else
            {
                <table class="table">
                    <tr>
                        <th colspan="2"><h3>Administration</h3></th>
                        <th colspan="2">
                            <RadzenTextBox Placeholder="Search..."
                                           @oninput="@(args => Search(args.Value.ToString(), "Search"))" />
                        </th>
                    </tr>
                </table>
                <table class="table">
                    <thead>
                        <tr>
                            <th>User Name</th>
                            <th>Email</th>
                            <th>Confirmed</th>
                            <th></th>
                        </tr>
                    </thead>
                    <tbody>
                        @foreach (var user in ColUsers.ApplicationUsers)
                        {
                        <tr>
                            <td>@user.UserName</td>
                            <td>@user.Email</td>
                            <td>@user.EmailConfirmed</td>
                            <td>
                                <button class="btn btn-primary"
                                        @onclick="(() => EditUser(user))">
                                    Edit
                                </button>
                            </td>
                        </tr>
                        }
                    </tbody>
                </table>
                <p>
                    <button class="btn btn-success" @onclick="AddNewUser">Add User</button>
                    @if (ShowPreviousButton)
                    {
                        <button class="btn btn-warning"
                                @onclick="Previous">
                            <b>&#x3C;</b>
                        </button>
                    }
                    @if (ShowNextButton)
                    {
                        <button class="btn btn-warning"
                                @onclick="Next">
                            <b>&#x3E;</b>
                        </button>
                    }
                </p>
            }
            @if (ShowPopup)
            {
                <!-- This is the popup to create or edit a user -->
                <div class="modal" tabindex="-1" style="display:block" role="dialog">
                    <div class="modal-dialog-scrollable modal-dialog-centered">
                        <div class="modal-content">
                            <div class="modal-header">
                                <h3 class="modal-title">Edit User</h3>
                                <!-- Button to close the popup -->
                                <button type="button" class="close"
                                        @onclick="ClosePopup">
                                    <span aria-hidden="true">X</span>
                                </button>
                            </div>
                            <!-- Edit form for the current forecast -->
                            <div class="modal-body">
                                <!-- Only allow edit if a new user -->
                                <b>User Name</b>
                                @if (objUser.Id != "")
                                {
                                    <p>@objUser.UserName</p>
                                }
                                else
                                {
                                    <input class="form-control" type="text"
                                           @bind="objUser.UserName" /><br />
                                }
                                <b>Display Name</b>
                                <input class="form-control" type="text"
                                       @bind="objUser.DisplayName" />
                                <br /><b>Email</b>
                                <input class="form-control" type="text"
                                       placeholder="Email"
                                       @bind="objUser.Email" />
                                <br /><b>Email Confirmed</b>
                                <select class="form-control"
                                        @bind="@EmailConfirmed">
                                    @foreach (var option in OptionsTrueFalse)
                                    {
                                        <option value="@option">
                                            @option
                                        </option>
                                    }
                                </select>
                                <br /><b>Newsletter Subscriber</b>
                                <select class="form-control"
                                        @bind="@NewsletterSubscriber">
                                    @foreach (var option in OptionsTrueFalse)
                                    {
                                        <option value="@option">
                                            @option
                                        </option>
                                    }
                                </select>
                                <br /><b>Role</b>
                                <select class="form-control"
                                        @bind="@CurrentUserRole">
                                    @foreach (var option in Options)
                                    {
                                        <option value="@option">
                                            @option
                                        </option>
                                    }
                                </select>
                                <br /><b>Password</b>
                                <input class="form-control" type="password"
                                       placeholder="Password"
                                       @bind="objUser.PasswordHash" />
                                <br /><br />
                                <!-- Button to save the user -->
                                <button class="btn btn-primary"
                                        @onclick="SaveUser">
                                    Save
                                </button>
                                <!-- Only show delete button if not a new record -->
                                <!-- and not the current user -->
                                @if (objUser.Id != "" && objUser.UserName.ToLower() != @context.User.Identity.Name.ToLower())
                                {
                                    <!-- Button to delete the forecast -->
                                    <button class="btn btn-danger"
                                            @onclick="DeleteUser">
                                        Delete
                                    </button>
                                }
                                <br />
                                <span style="color:red">@strError</span>
                            </div>
                        </div>
                    </div>
                </div>
            }
        }
        else
        {
            <p>You are not signed in as a user in @ADMINISTRATION_ROLE.</p>
        }
    </Authorized>
    <NotAuthorized>
        <h3>Administration</h3>
        <p>You are not logged in.</p>
    </NotAuthorized>
</AuthorizeView>
@code {
    [CascadingParameter]
    private Task<AuthenticationState> authenticationStateTask { get; set; }

    string ADMINISTRATION_ROLE = "Administrators";
    ApplicationUser objUser = new ApplicationUser();
    ApplicationUserPaged ColUsers = new ApplicationUserPaged() { ApplicationUsers = new List<ApplicationUser>(), ApplicationUserCount = 0 };

    List<string> Options = new List<string>() { "Users", "Administrators" };
    List<string> OptionsTrueFalse = new List<string>() { "True", "False" };
    System.Security.Claims.ClaimsPrincipal CurrentUser;
    string EmailConfirmed { get; set; } = "False";
    string NewsletterSubscriber { get; set; } = "False";
    string CurrentUserRole { get; set; } = "Users";
    string strError = "";
    string strSearch = "";
    bool ShowPopup = false;

    int CurrentPage = 1;
    bool ShowPreviousButton { get { return (CurrentPage > 1); } }
    bool ShowNextButton { get { return ((ColUsers.ApplicationUserCount > (CurrentPage * 5))); } }

    protected override async Task OnInitializedAsync()
    {
        // Get the current logged in user
        CurrentUser = (await authenticationStateTask).User;

        // Get the users
        await GetUsers();

        DisqusState.SetDisplayDisqus(false);
    }

    public async Task GetUsers()
    {
        // clear any error messages
        strError = "";

        ColUsers = await @Service.GetUsersAsync(strSearch, CurrentPage);
    }

    void ClosePopup()
    {
        // Close the Popup
        ShowPopup = false;
    }

    void AddNewUser()
    {
        // Make new user
        objUser = new ApplicationUser();
        objUser.PasswordHash = "*****";

        // Set Id to blank so we know it is a new record
        objUser.Id = "";

        // Open the Popup
        ShowPopup = true;
    }

    async Task SaveUser()
    {
        try
        {
            // Is this an existing user?
            if (objUser.Id != "")
            {
                // Get the user
                var user = await _UserManager.FindByIdAsync(objUser.Id);

                // Update Email
                user.Email = objUser.Email;

                // Update DisplayName
                user.DisplayName = objUser.DisplayName;

                // Set Email Confirmed
                user.EmailConfirmed = Convert.ToBoolean(EmailConfirmed);

                // Set NewsletterSubscriber
                user.NewsletterSubscriber = Convert.ToBoolean(NewsletterSubscriber);

                // Update the user
                await _UserManager.UpdateAsync(user);

                // Only update password if the current value
                // is not the default value
                if (objUser.PasswordHash != "*****")
                {
                    var resetToken = await _UserManager.GeneratePasswordResetTokenAsync(user);
                    var passworduser = await _UserManager.ResetPasswordAsync(user, resetToken, objUser.PasswordHash);

                    if (!passworduser.Succeeded)
                    {
                        if (passworduser.Errors.FirstOrDefault() != null)
                        {
                            strError = passworduser.Errors.FirstOrDefault().Description;
                        }
                        else
                        {
                            strError = "Pasword error";
                        }

                        // Keep the popup opened
                        return;
                    }
                }

                // Handle Roles

                // Is user in administrator role?
                var UserResult = await _UserManager.IsInRoleAsync(user, ADMINISTRATION_ROLE);

                // Is Administrator role selected but user is not an Administrator?
                if ((CurrentUserRole == ADMINISTRATION_ROLE) & (!UserResult))
                {
                    // Put admin in Administrator role
                    await _UserManager.AddToRoleAsync(user, ADMINISTRATION_ROLE);
                }
                else
                {
                    // Is Administrator role not selected but user is an Administrator?
                    if ((CurrentUserRole != ADMINISTRATION_ROLE) & (UserResult))
                    {
                        // Remove user from Administrator role
                        await _UserManager.RemoveFromRoleAsync(user, ADMINISTRATION_ROLE);
                    }
                }
            }
            else
            {
                // Insert new user

                var NewUser =
                    new ApplicationUser
                    {
                        UserName = objUser.UserName,
                        DisplayName = objUser.DisplayName,
                        Email = objUser.Email
                    };

                NewUser.EmailConfirmed = Convert.ToBoolean(EmailConfirmed);
                NewUser.NewsletterSubscriber = Convert.ToBoolean(NewsletterSubscriber);

                var CreateResult = await _UserManager.CreateAsync(NewUser, objUser.PasswordHash);

                if (!CreateResult.Succeeded)
                {
                    if (CreateResult.Errors.FirstOrDefault() != null)
                    {
                        strError = CreateResult.Errors.FirstOrDefault().Description;
                    }
                    else
                    {
                        strError = "Create error";
                    }

                    // Keep the popup opened
                    return;
                }
                else
                {
                    // Handle Roles
                    if (CurrentUserRole == ADMINISTRATION_ROLE)
                    {
                        // Put admin in Administrator role
                        await _UserManager.AddToRoleAsync(NewUser, ADMINISTRATION_ROLE);
                    }
                }
            }

            // Close the Popup
            ShowPopup = false;

            // Refresh Users
            await GetUsers();
        }
        catch (Exception ex)
        {
            strError = ex.GetBaseException().Message;
        }
    }

    async Task EditUser(ApplicationUser _IdentityUser)
    {
        // Set the selected user
        // as the current user
        objUser = _IdentityUser;

        // Get the user
        var user = await _UserManager.FindByIdAsync(objUser.Id);

        if (user != null)
        {
            // Is user in administrator role?
            var UserResult = await _UserManager.IsInRoleAsync(user, ADMINISTRATION_ROLE);

            if (UserResult)
            {
                CurrentUserRole = ADMINISTRATION_ROLE;
            }
            else
            {
                CurrentUserRole = "Users";
            }

            if (user.EmailConfirmed)
            {
                EmailConfirmed = "True";
            }
            else
            {
                EmailConfirmed = "False";
            }

            if (user.NewsletterSubscriber)
            {
                NewsletterSubscriber = "True";
            }
            else
            {
                NewsletterSubscriber = "False";
            }
        }

        // Open the Popup
        ShowPopup = true;
    }

    async Task DeleteUser()
    {
        // Close the Popup
        ShowPopup = false;

        // Get the user
        var user = await _UserManager.FindByIdAsync(objUser.Id);
        if (user != null)
        {
            // Delete the user
            await _UserManager.DeleteAsync(user);
        }

        // Refresh Users
        await GetUsers();
    }

    // Search

    async Task Search(string value, string name)
    {
        // Update search value
        strSearch = value;

        // Switch to page 1
        CurrentPage = 1;

        // Refresh Users
        await GetUsers();
    }

    // Paging

    async Task Previous()
    {
        if (CurrentPage > 1)
        {
            CurrentPage = CurrentPage - 1;
            // Refresh Users
            await GetUsers();
        }
    }

    async Task Next()
    {
        CurrentPage = CurrentPage + 1;
        // Refresh Users
        await GetUsers();
    }
}
